(define-module (opensmtpd)
  #:use-module (guix gexp)
  #:use-module (guix records)
  #:use-module (gnu packages mail) ;;for finding location of filter-dkimsign
  #:export (
            %smtpd.conf
            ))


;; to create credentials for now, I need to do the following:
;;  find /gnu/store -name '*encrypt*' | grep opensmtpd
;; /gnu/store/blah/opensmtpd/encrypt 
(define creds
  (plain-file "creds"
              ;; this is my joshua's password for server.  This can be found on dobby's /home/joshua/.authinfo/
              "joshua $6$Ec4m8FgKjT2F/03Y$k66ABdse9TzCX6qaALB3WBL9GC1rmAWJmaoSjFMpbhzat7DOpFqpnOwpbZ34wwsQYIK8RQlqwM1I/v6vsRq86."))

(define vdoms
  (plain-file
   "vdoms"
   "gnucode.me
gnu-hurd.com"))

(define vusers
  (plain-file
   "vusers"
   "joshua@gnucode.me  joshua
jbranso@gnucode.me     joshua
postmaster@gnucode.me  joshua"))

(define path-to-filter-dkimsign
  (file-append opensmtpd-filter-dkimsign "/libexec/opensmtpd/filter-dkimsign"))

(define path-to-dkimsign-key (string-append (getcwd) "/email-dkim-ssh-keys/2021-09-22-rsa1024-gnucode.me.key"))
(define etc-dkimsign-key-file "/etc/opensmtpd/dkimsign/2021-09-22-rsa1024-gnucode.me.key")

;; FIXME:  This should become a derivation.  Currently it just runs when I evaluate
;; %smtpd.conf.  For example it should look like this?
;; (define build-exp
;;   #~(begin
;;       (mkdir #$output)
;;       (chdir #$output)
;;       (symlink (string-append #$coreutils "/bin/ls")
;;                "list-files")))

;; I will need to extend the opensmtpd service, to create a directory
;; in etc.  This line needs to be added to etc-service.
;; (service-extension etc-service-type opensmtpd-etc-service)
;; I'll then need to create a opensmtpd-etc-service procedure.  ganeti has
;; a good example.

;; It should also use the /etc service, which is a service for creating
;; directories and files in /etc ?
(define (create-etc-dkimsign-key-file)
  #~(let ([UID-nobody (passwd:uid (getpw "nobody"))]
          [GID-root (group:gid (getgr "root"))]
          [GID-nogroup (group:gid (getgr "nogroup"))])
    ;; #o550 user root can read/open the directory
    ;; and the group "root" can read/open the directory.
    ;; change these two lines to (mkdir-p) ?
      (unless (file-exists? "/etc/opensmtpd")
        (mkdir "/etc/opensmtpd" #o550))

      ;; root can read/write/execute on directory dkimsign
      ;; group "root" can read and execute
      (unless (file-exists? "/etc/opensmtpd/dkimsign")
        (mkdir "/etc/opensmtpd/dkimsign" #o750))

      (copy-file path-to-dkimsign-key etc-dkimsign-key-file)
      ;; ;; ;; make the etc-dkimsign-key-file to owned by nobody and group nogroup.
      (chown "/etc/opensmtpd" UID-nobody GID-root)
      (chown "/etc/opensmtpd/dkimsign" UID-nobody GID-root)
      (chown etc-dkimsign-key-file UID-nobody GID-nogroup)
      etc-dkimsign-key-file))

(define %smtpd.conf
  (mixed-text-file "smtpd.conf"
                   "
# This is the smtpd server system-wide configuration file.
# See smtpd.conf(5) for more information.
# borrowed from the archlinux guix
# https://wiki.archlinux.org/index.php/OpenSMTPD#Simple_OpenSMTPD/mbox_configuration

# My TLS certificate and key
table aliases file:/etc/aliases
pki smtp.gnucode.me cert \"/etc/letsencrypt/live/gnucode.me/fullchain.pem\"
pki smtp.gnucode.me key \"/etc/letsencrypt/live/gnucode.me/privkey.pem\"

# for now I am NOT using the virtual credentials
# table creds { joshua = $6$Ec4m8FgKjT2F/03Y$k66ABdse9TzCX6qaALB3WBL9GC1rmAWJmaoSjFMpbhzat7DOpFqpnOwpbZ34wwsQYIK8RQlqwM1I/v6vsRq86. }
table creds \"" creds "\"
table vdoms \"" vdoms "\"
# table vdoms { gnucode.me, gnu-hurd.com }
# table vusers { joshua@gnucode.me = joshua, jbranso@gnucode.me = joshua, postmaster@gnucode.me = joshua }
table vusers \"" vusers "\"

# this totally works!  run this as user nobody!
# info about dkimsign ...ing
# https://openports.pl/path/mail/opensmtpd-filters/dkimsign
# sudo -u nobody /gnu/store/g17vdv4l03bacn7qbdpb5v8l8vgdxcld-opensmtpd-filter-dkimsign-0.5/libexec/opensmtpd/filter-dkimsign -d gnucode.me -s 2020 -c relaxed/relaxed -k etc-dkimsign-key-file /home/joshua/linode-guix-system-configuration/email-dkim-ssh-keys/20201004-gnucode.me.key user nobody group nogroup

filter \"dkimsign\"  \
  proc-exec \"" path-to-filter-dkimsign " -d gnucode.me -s 2021-09-22 -c relaxed/relaxed -k " etc-dkimsign-key-file ;;(create-etc-dkimsign-key-file)
  " \"  \
  user nobody group nogroup

# port 25 is used only for receiving from external servers, and they may start a
# TLS session if the want.
listen on eth0 port 25 tls pki smtp.gnucode.me

# For sending messages from outside of this server, you need to authenticate and use
# TLS
listen on eth0 port 465 smtps pki smtp.gnucode.me auth <creds> filter \"dkimsign\"
listen on eth0 port 587 tls-require pki smtp.gnucode.me auth <creds> filter \"dkimsign\"

# users logged-in/ssh-ed into the system can send email
listen on lo port 25 tls pki smtp.gnucode.me

# receive email action
action \"receive\" maildir \"/home/%{rcpt.user}/Maildir\" junk virtual <vusers>
# action send the email to the world
action \"send\" relay

# We accept to send email from any mail from authenticated users
match for any from any auth action \"send\"

#finally we receive any incoming email
# maybe the next \"from any\" should be changed to \"for rdns\".
match from any for domain <vdoms> action \"receive\"
match for local action \"receive\""))
